package com.zdpx.pxframework.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdpx.pxframework.system.entity.DepartmentInfo;
import com.zdpx.pxframework.system.entity.UserDepartment;
import com.zdpx.pxframework.system.mapper.DepartmentInfoMapper;
import com.zdpx.pxframework.system.service.DepartmentInfoService;
import com.zdpx.pxframework.system.service.UserDepartmentService;
import com.zdpx.pxframework.system.vo.vo.DepartmentTreeVo;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.zdpx.pxframework.core.constant.RedisKeyConstant.DEPT_CHILDREN_IDS_KEY;


/**
 * 部门信息 服务实现类
 *
 * @Description:
 * @Author: Cheng XiaoXiao
 * @Date: 2022-02-27 15:20:14
 */
@Service
public class DepartmentInfoServiceImpl extends ServiceImpl<DepartmentInfoMapper, DepartmentInfo> implements DepartmentInfoService {
    @Resource
    UserDepartmentService userDepartmentService;

    /**
     * 获取部门详情
     *
     * @param id ID
     * @return 单个部门详情
     */
    @Override
    public DepartmentInfo detailById(String id) {
        return this.getById(id);
    }

    /**
     * 增加部门信息
     *
     * @param departmentInfo 部门对象
     */
    @Override
    @CacheEvict(value = DEPT_CHILDREN_IDS_KEY)
    public void saveDepartmentInfo(DepartmentInfo departmentInfo) {
        this.baseMapper.insert(departmentInfo);
    }

    /**
     * 修改部门信息
     *
     * @param departmentInfo 部门对象
     */
    @Override
    @CacheEvict(value = DEPT_CHILDREN_IDS_KEY)
    public void updateDepartmentInfoById(DepartmentInfo departmentInfo) {
        this.baseMapper.updateById(departmentInfo);
    }

    /**
     * 根据ID删除
     *
     * @param id ID
     */
    @Override
    public void deleteById(String id) {
        this.removeById(id);
    }

    /**
     * 递归处理获取子节点
     *
     * @param departmentInfo 当前树节点
     * @param allDepartment  所有的树节点
     * @return 包含子节点的树结构
     */
    private DepartmentTreeVo treeSelectChildren(DepartmentInfo departmentInfo, List<DepartmentInfo> allDepartment) {
        DepartmentTreeVo departmentTreeVo = new DepartmentTreeVo();
        BeanUtil.copyProperties(departmentInfo, departmentTreeVo);

        if (departmentTreeVo.getChildren() == null) {
            departmentTreeVo.setChildren(new ArrayList<DepartmentTreeVo>());
        }

        for (DepartmentInfo item : allDepartment) {
            if (item.getParentId().equals(departmentInfo.getId())) {
                departmentTreeVo.getChildren().add(treeSelectChildren(item, allDepartment));
            }
        }
        return departmentTreeVo;
    }

    /**
     * 查询部门树形结构
     *
     * @return 部门树形结构
     */
    @Override
    public List<DepartmentTreeVo> tree() {
        List<DepartmentInfo> allDepartment = listAllOrderById();

        List<DepartmentTreeVo> list = new ArrayList<>();

        //进行递归查询，封装成树结构
        for (DepartmentInfo departmentInfo : allDepartment) {
            if ("0".equals(departmentInfo.getParentId())) {
                //存在多个一级节点
                list.add(treeSelectChildren(departmentInfo, allDepartment));
            }
        }

        return list;
    }


    /**
     * 根据用户ID获取部门ID列表信息
     *
     * @param userId 用户ID
     * @return 部门列表ID
     */
    @Override
    public List<String> lisDepartmentIdsByUserId(String userId) {
        List<UserDepartment> userDepartmentList = userDepartmentService.list(new LambdaQueryWrapper<UserDepartment>()
                .select(UserDepartment::getDepartmentId)
                .eq(UserDepartment::getUserId, userId));

        return userDepartmentList.stream().map(UserDepartment::getDepartmentId).collect(Collectors.toList());
    }

    /**
     * 根据父id查询子ID列表
     *
     * @param parentId 父ID
     * @return 子id列表
     */
    @Override
    @Cacheable(value = DEPT_CHILDREN_IDS_KEY, key = "#parentId")
    public List<String> listChildrenIdsByParentId(String parentId) {
        List<DepartmentInfo> allDepartment = listAllOrderById();

        List<String> list = new ArrayList<>();
        //进行递归查询，封装成id集合
        for (DepartmentInfo departmentInfo : allDepartment) {
            if (parentId.equals(departmentInfo.getParentId())) {
                treeChildrenId(departmentInfo, allDepartment, list);
            }
        }
        return list;
    }

    /**
     * 递归组装子节点ID
     *
     * @param departmentInfo 当前部门信息
     * @param allDepartment  所有数据
     * @param childrenList   子节点的列表
     */
    private void treeChildrenId(DepartmentInfo departmentInfo, List<DepartmentInfo> allDepartment, List<String> childrenList) {
        for (DepartmentInfo item : allDepartment) {
            if (item.getParentId().equals(departmentInfo.getId())) {
                childrenList.add(item.getId());
                treeChildrenId(item, allDepartment, childrenList);
            }
        }
    }

    /**
     * 查询所有根据id排序
     *
     * @return 部门集合
     */
    private List<DepartmentInfo> listAllOrderById() {
        return this.list(new LambdaQueryWrapper<DepartmentInfo>().orderByAsc(DepartmentInfo::getId));
    }


}
